package com.atguigu.mq.listener;

import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

@Component
@Slf4j
public class MyMessageListener {

    //@RabbitListener(queues = "atguigu.queue.direct02")

    /**
     * durable = "true"     是否为持久化队列，服务器重启，队列是否还存在。推荐true
     * exclusive = "false"  是否为排他队列，排他队列只限于当前连接使用，连接关闭，队列会被删除。推荐false
     * autoDelete = "false"  是否为自动删除队列。长时间不使用，服务器会删除队列。推荐false
     * declare = "true"     是否为自动声明的队列。不存在就创建，在就使用。
     *
     */
    /*@RabbitListener(
            bindings = {
                    @QueueBinding(
                            value= @Queue(name="atguigu.queue.direct02",durable = "true",
                                    arguments = { //给队列设置参数
                                        @Argument(name = "x-message-ttl",value = "10000",type = "long")
                                    },
                                    exclusive = "false",autoDelete = "false",declare = "true"),
                            exchange = @Exchange(name="atguigu.exchange.direct",durable = "true"),
                            key = {
                                "b","c","a"
                            }
                    )
            }
    )
    public void processMessage(String dataString, Message message, Channel channel) throws  Exception {
        long deliveryTag = message.getMessageProperties().getDeliveryTag(); //消息唯一标识。id
        try {
            log.info("dataString="+dataString);

            //假设业务逻辑失败
            //int i = 1/0;

            channel.basicAck(deliveryTag,false); //手动确认    multiple=true表示一次确认多条消息，效率高；重要消息推荐一条一条确认.multiple=false
        } catch (Exception e) {
            //e.printStackTrace();
            Boolean redelivered = message.getMessageProperties().getRedelivered(); //是否为重复投递的消息
            if(redelivered){  // true表示消息为重复投递
                channel.basicReject(deliveryTag,false); //requeue=false表示要么丢弃，要么去死信队列。
            }else{ //首次投递
                channel.basicNack(deliveryTag,false,true); //requeue=true 表示回到原队列，可以重新再进行投递。
            }

        }
    }*/


    //正常消费者
    @RabbitListener(queues = {"queue.normal.video"}) //监听正常队列
    public void processMessageNormal(String msg,Message message, Channel channel) throws IOException {
        // 监听正常队列，但是拒绝消息
        log.info("★[normal]消息接收到，但我拒绝。");
        channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);
    }


    //死信消费者
    @RabbitListener(queues = {"queue.dead.letter.video"}) //监听死信队列
    public void processMessageDead(String msg,Message message, Channel channel) throws IOException {
        // 监听正常队列，但是拒绝消息
        log.info("★[Dead]消息接收到，由死信消费者处理。");
        //直接拒绝，不给服务器确认，还不让回到原有队列(requeue=false),要么丢弃，要么去到死信队列。
        channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);
    }



    //延迟消息的消费者
    //@RabbitListener(queues = {"queue.delayed.direct"}) //监听死信队列
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "queue.delayed.direct", durable = "true", autoDelete = "false"),
            exchange = @Exchange(
                    value = "exchange.delayed.direct",
                    durable = "true",
                    autoDelete = "false",
                    type = "x-delayed-message",
                    arguments = @Argument(name = "x-delayed-type", value = "direct")),
            key = {"delayed.key"}
    ))
    public void processMessageDelayed(String msg,Message message, Channel channel) throws IOException {
        // 监听正常队列，但是拒绝消息
        log.info("当前时间："+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) +"延迟消息为："+msg);
        //直接拒绝，不给服务器确认，还不让回到原有队列(requeue=false),要么丢弃，要么去到死信队列。
        channel.basicReject(message.getMessageProperties().getDeliveryTag(), false);
    }
}
